/*
    DIMVisual, the Data Integration Model for Visualization of trace files.
    Copyright (c) 2008 Lucas Mello Schnorr <schnorr@gmail.com>

    This file is part of DIMVisual.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "Command.h"

@implementation Command

/*
 *
 */
- (void) helpCommandOfSingleBundle: (NSDictionary *) conf
{
	int j;

	NSString *bundleid = [conf objectForKey: @"ID"];
	NSDictionary *parameters = [conf objectForKey: @"parameters"];	
	NSArray *allKeys = [parameters allKeys];

	for (j = 0; j < [allKeys count]; j++){
//		NSDictionary *singlepar = [parameters objectAtIndex: j];
//		NSString *key = [[allKeys objectAtIndex: j] objectAtIndex: 0];
		NSString *value = [parameters objectForKey: [allKeys objectAtIndex: j]];
		fprintf (stderr, 
			"\t\t-%s-%s {%s}\n", [[bundleid description] cString], 
				[[[allKeys objectAtIndex: j] description] cString],
				[[value description] cString]);
	}	
}

/*
 *
 */
- (void) listCommand
{
	int i;
	NSArray *list = [bundleCenter listBundlesAvailable];
	fprintf (stderr, "DIMVisual available bundles:\n");
	for (i = 0; i < [list count]; i++){
		fprintf (stderr, "\t%s\n", [[list objectAtIndex: i] cString]);
		[self helpCommandOfSingleBundle: [bundleCenter configurationForBundleWithName: [list objectAtIndex: i]]];
	}
	if ([list count] == 0){
		fprintf (stderr, "\tNo bundles available.\n");
	}
}

/*
 *
 */
- (void) helpCommand
{
	fprintf (stderr, 
		"DIMVisual help: \n"
		"  %s (this text)\n"
		"  %s {directory} (specify where to search bundles)\n"
		"  %s {dataSource1 ... dataSourceN} (separated by space)\n",
		HELP_COMMAND, BUNDLEDIR_COMMAND, LOAD_COMMAND);
	[self listCommand];
}

/*
 *
 */
- (void) bundledirCommand
{
	int i;

	NSMutableArray *dirs = [configuration valueForKey: [NSString stringWithCString: BUNDLEDIR_COMMAND]];
	for (i = 0; i < [dirs count]; i++){
		[bundleCenter addBundleDirectory: [dirs objectAtIndex: i]];
	}	
}

/*
 *
 */
- (BOOL) loadCommand
{
	int i;

	NSArray *bundlesToLoad = [configuration valueForKey: [NSString stringWithCString: LOAD_COMMAND]];
	for (i = 0; i < [bundlesToLoad count]; i++){
		NSString *name = [bundlesToLoad objectAtIndex: i];
		if ([bundleCenter loadBundleWithName: name] == NO){
			NSLog (@"Could not load bundle named '%@'", name);
			return NO;
		}else{
			return YES;
		}
	}
	return NO;
}


/*
 *
 */
- (BOOL) outputCommand
{
	NSArray *files = [configuration valueForKey: [NSString stringWithCString: OUTPUT_COMMAND]];

	if (configured == nil){
		configured = [[NSMutableDictionary alloc] init];
	}
	if (files == nil || [files count] == 0){
		NSLog (@"###");
		return NO;
	}

	NSMutableDictionary *selfConf;
	selfConf = [configured objectForKey: @"DIMVISUAL"];
	if (selfConf == nil){
		selfConf = [[NSMutableDictionary alloc] init];
		[configured setObject: selfConf forKey: @"DIMVISUAL"];
	}
	[selfConf setObject: [files objectAtIndex: 0] forKey: @"output"];
	return YES;
}

/*
 *
 */
- (id) initWithArgc: (int) argc andArgv: (char **) argv
{
	int i, j;

	self = [super init];

	bundleCenter = [[BundleCenter alloc] init];
	configured = [[NSMutableDictionary alloc] init];
	pathOfProgramExecution = [[NSFileManager defaultManager] currentDirectoryPath];

	/* Phase 1: Transforms argv and argc in a dictionary (configuration) */
	configuration = [[NSMutableDictionary alloc] init];
	for (i = 1; i < argc; i++){
		if (argv[i][0] == '-'){
			NSString *parameter;
			NSMutableArray *values;

			parameter = [NSString stringWithCString: argv[i]];
			values = [NSMutableArray array];

			for (j = i+1; j < argc && argv[j][0] != '-'; j++){
				[values addObject:
					[NSString stringWithCString: argv[j]]];
			}
			[configuration setObject: values forKey: parameter];
		}
	}
	
	/* Phase 2: Analyse the configuration parsed, searching */
	if ([configuration objectForKey: [NSString stringWithCString: HELP_COMMAND]]){
		[self helpCommand];
		return nil; 
	}

	if ([configuration objectForKey: [NSString stringWithCString: BUNDLEDIR_COMMAND]]){
		[self bundledirCommand];
	}	

	if ([configuration objectForKey: [NSString stringWithCString: LIST_COMMAND]]){
		[self listCommand];
		return nil;
	}

	if ([configuration objectForKey: [NSString stringWithCString: LOAD_COMMAND]]){
		if ([self loadCommand] == NO){
			return nil;
		}
	}

	if ([configuration objectForKey: [NSString stringWithCString: OUTPUT_COMMAND]]){
		if ([self outputCommand] == NO){
			//return nil;
		}
	}else{
		NSLog (@"Warning: Missing %s parameter (optional when used as library)", OUTPUT_COMMAND);
		//return nil;
	}


	/* Phase 3: Analyse the parameters of loaded bundles */
	[configured setObject: [bundleCenter configureBundlesWithThis: configuration] forKey: @"Bundles"];


	[[NSFileManager defaultManager] changeCurrentDirectoryPath: pathOfProgramExecution];
	return self;
}

/*
 *
 */
- (NSDictionary *) configuration
{
	return (NSDictionary *)configured;
}
@end
